using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using MacomberMap.Common.Database_Interface.CIM.Components;
using MacomberMap.Common.Components;
using System.ComponentModel;
using MacomberMap.Common.User_Interfaces.One_Lines;
using System.Drawing;
using MacomberMap.Common.User_Interfaces.One_Lines.Elements;

namespace MacomberMap.Common.Database_Interface.CIM.One_Line_Interface
{
    /// <summary>
    /// This class overloads the list view item, providing MM and CIM linkages
    /// </summary>
    public class CIMListViewItem: ListViewItem, IComparable<CIMListViewItem>
    {
        #region Variable declarations        
        /// <summary>The one-line viewer</summary>
        private MM_OneLine_Viewer olView;

        /// <summary>The CIM element associated with the list view item</summary>
        public CIM_Element CIMElement
        {
            get { return _CIMElement; }
            set { _CIMElement = value; }
        }
        private CIM_Element _CIMElement;

        /// <summary>
        /// The MM element associated with the list view item
        /// </summary>
        [Category("Data"),Description("The MM element associated with the list view item")]
        public MM_Element MMElement
        {
            get { return _MMElement; }
            set { _MMElement = value; }
        }
        private MM_Element _MMElement;

        /// <summary>
        /// The one-line element associated with the list view item
        /// </summary>
        [Category("Data"), Description("The one-line element associated with the list view item")]
        public MM_OneLine_Linked OLElement
        {
            get
            {
                if (_MMElement.ElemType.Name == "TransformerWinding" && olView.TransformerWindings.ContainsKey(_MMElement))
                    return olView.TransformerWindings[_MMElement];
                else if (_MMElement is MM_BusbarSection && (_MMElement as MM_BusbarSection).AssociatedNode != null && olView.DisplayElements.ContainsKey((_MMElement as MM_BusbarSection).AssociatedNode))
                    return olView.DisplayElements[(_MMElement as MM_BusbarSection).AssociatedNode];
                else if (olView.DisplayElements.ContainsKey(MMElement))
                    return olView.DisplayElements[MMElement];
                else if (olView.DisplayNodes.ContainsKey(MMElement))
                    return olView.DisplayNodes[MMElement];
                else
                    return null;
            }
        }           
        #endregion

        #region Initialization
        /// <summary>
        /// Initialize a new CIM List view item
        /// </summary>        
        /// <param name="BaseElement">The base element</param>
        /// <param name="MMElement">The MM representation of the element</param>
        /// <param name="olView">The one-line viewer</param>
        public CIMListViewItem(CIM_Element BaseElement, MM_Element MMElement, MM_OneLine_Viewer olView)
        {            
            this.CIMElement = BaseElement;
            this.olView = olView;
            this.MMElement = MMElement;
            this.Name = BaseElement.TEID;
            this.Text = this.MMElement.Name;
            if (this.MMElement.KVLevel != null)
                this.SubItems.Add(this.MMElement.KVLevel.Name);
            else
                this.SubItems.Add("");
            this.SubItems.Add(this.MMElement.TEID.ToString("#,##0"));
            UpdateState();
        }

        /// <summary>
        /// Update the state of the element, displaying it in red or white depending on state
        /// </summary>
        public void UpdateState()
        {
            if (OLElement == null)
                this.ForeColor = Color.Red;
            else if (OLElement is MM_OneLine_Node && OLElement.BaseElement is MM_Node)
            {
              
                this.ForeColor = Color.White;
                MM_OneLine_Node BaseNode = OLElement as MM_OneLine_Node;

                //First, see if there are any elements referred into the node that doesn't exist
                foreach (MM_Element Elem in (BaseNode.BaseElement as MM_Node).ConnectedElements)                    
                    if (Elem is MM_PricingVector == false && olView.DisplayElements.ContainsKey(Elem) && !BaseNode.ConnectionPoints.ContainsKey(olView.DisplayElements[Elem]))
                        this.ForeColor = Color.Yellow;

                //Now, see if there are any incorrectly referred elements
                foreach (MM_OneLine_Element Elem in BaseNode.ConnectionPoints.Keys)
                    if (Elem is MM_OneLine_Transformer)
                    {
                        bool FoundWinding = false;
                        foreach (MM_OneLine_TransformerWinding Winding in (Elem as MM_OneLine_Transformer).Windings)
                            if (Winding != null && Array.IndexOf<MM_Element>((BaseNode.BaseElement as MM_Node).ConnectedElements, Winding.BaseElement) != -1)
                                FoundWinding = true;
                        if (!FoundWinding)
                            this.ForeColor = Color.Yellow;
                    }

                    else if (BaseNode.BaseElement != Elem.BaseElement && Array.IndexOf<MM_Element>((BaseNode.BaseElement as MM_Node).ConnectedElements, Elem.BaseElement) == -1)
                        this.ForeColor = Color.Yellow;
            }
            else
                this.ForeColor = Color.White;
                
        }
        #endregion

        #region IComparable<CIMListViewItem> Members
        /// <summary>
        /// Compare two CIM List view elements
        /// </summary>
        /// <param name="other"></param>
        /// <returns></returns>
        public int CompareTo(CIMListViewItem other)
        {
            return String.Compare(Text, other.Text, true);                
        }

        #endregion
    }
}
